/*
 * jxSwing Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxSwing.component.panel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.TextComponent;
import java.awt.event.InputMethodListener;
import java.awt.event.MouseEvent;
import java.awt.im.InputMethodRequests;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.beans.Transient;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.text.MessageFormat;

import javax.accessibility.AccessibleContext;
import javax.print.PrintService;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.Action;
import javax.swing.DropMode;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.event.CaretListener;
import javax.swing.plaf.TextUI;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.JTextComponent.DropLocation;
import javax.swing.text.JTextComponent.KeyBinding;
import javax.swing.text.Keymap;
import javax.swing.text.NavigationFilter;
import javax.swing.text.PlainDocument;

import org.jxSwing.component.JXComponent;
import org.jxSwing.component.text.TextArea;
import org.jxSwing.i18n.I18N;
import org.jxUtils.check.CheckUtil;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.panel
 * @date 15/11/2014 - 21:16:48
 */
public class TextAreaPanel extends JPanel implements JXComponent {
	
	private static final long serialVersionUID = -400566391547982967L;
	
	private JScrollPane scrollPane;
	
	private TextArea textArea;
	
	private boolean requiredBorderEnabled = true;
	
	/**
	 * 
	 */
	public TextAreaPanel() {
	
		textArea = new TextArea();
		
		initGUI();
	}
	
	/**
	 * @param doc
	 */
	public TextAreaPanel(Document doc) {
	
		textArea = new TextArea(doc);
		
		initGUI();
	}
	
	/**
	 * @param doc
	 * @param text
	 * @param rows
	 * @param columns
	 */
	public TextAreaPanel(Document doc, String text, int rows, int columns) {
	
		textArea = new TextArea(doc, text, rows, columns);
		
		initGUI();
	}
	
	/**
	 * @param rows
	 * @param columns
	 */
	public TextAreaPanel(int rows, int columns) {
	
		textArea = new TextArea(rows, columns);
		
		initGUI();
	}
	
	/**
	 * @param text
	 */
	public TextAreaPanel(String text) {
	
		textArea = new TextArea(text);
		
		initGUI();
	}
	
	/**
	 * @param text
	 * @param rows
	 * @param columns
	 */
	public TextAreaPanel(String text, int rows, int columns) {
	
		textArea = new TextArea(text, rows, columns);
		
		initGUI();
	}
	
	/**
	 * Adds a new keymap into the keymap hierarchy. Keymap bindings
	 * resolve from bottom up so an attribute specified in a child
	 * will override an attribute specified in the parent.
	 *
	 * @param nm
	 *        the name of the keymap (must be unique within the
	 *        collection of named keymaps in the document); the name may
	 *        be <code>null</code> if the keymap is unnamed,
	 *        but the caller is responsible for managing the reference
	 *        returned as an unnamed keymap can't
	 *        be fetched by name
	 * @param parent
	 *        the parent keymap; this may be <code>null</code> if
	 *        unspecified bindings need not be resolved in some other keymap
	 * @return the keymap
	 */
	public static Keymap addKeymap(String nm, Keymap parent) {
	
		return JTextComponent.addKeymap(nm, parent);
	}
	
	/**
	 * Fetches a named keymap previously added to the document.
	 * This does not work with <code>null</code>-named keymaps.
	 *
	 * @param nm
	 *        the name of the keymap
	 * @return the keymap
	 */
	public static Keymap getKeymap(String nm) {
	
		return JTextComponent.getKeymap(nm);
	}
	
	/**
	 * <p>
	 * Loads a keymap with a bunch of bindings. This can be used to take a static table of definitions and load them into some keymap. The following example illustrates an example of binding some keys to the cut, copy, and paste actions associated with a JTextComponent. A code fragment to accomplish this might look as follows:
	 * 
	 * <pre>
	 * <code>
	 * 
	 *   static final JTextComponent.KeyBinding[] defaultBindings = {
	 *     new JTextComponent.KeyBinding(
	 *       KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK),
	 *       DefaultEditorKit.copyAction),
	 *     new JTextComponent.KeyBinding(
	 *       KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK),
	 *       DefaultEditorKit.pasteAction),
	 *     new JTextComponent.KeyBinding(
	 *       KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK),
	 *       DefaultEditorKit.cutAction),
	 *   };
	 * 
	 *   JTextComponent c = new JTextPane();
	 *   Keymap k = c.getKeymap();
	 *   JTextComponent.loadKeymap(k, defaultBindings, c.getActions());
	 * 
	 * </code>
	 * </pre>
	 * 
	 * The sets of bindings and actions may be empty but must be non-<code>null</code>.
	 *
	 * @param map
	 *        the keymap
	 * @param bindings
	 *        the bindings
	 * @param actions
	 *        the set of actions
	 */
	public static void loadKeymap(Keymap map, KeyBinding[] bindings, Action[] actions) {
	
		JTextComponent.loadKeymap(map, bindings, actions);
	}
	
	/**
	 * Removes a named keymap previously added to the document. Keymaps
	 * with <code>null</code> names may not be removed in this way.
	 *
	 * @param nm
	 *        the name of the keymap to remove
	 * @return the keymap that was removed
	 */
	public static Keymap removeKeymap(String nm) {
	
		return JTextComponent.removeKeymap(nm);
	}
	
	/**
	 *
	 */
	private void initGUI() {
	
		getTextArea().setRequiredBorderEnabled(false);
		
		setLayout(new BorderLayout());
		
		add(getScrollPane(), BorderLayout.CENTER);
	}
	
	/**
	 * Adds a caret listener for notification of any changes
	 * to the caret.
	 *
	 * @param listener
	 *        the listener to be added
	 * @see javax.swing.event.CaretEvent
	 */
	public void addCaretListener(CaretListener listener) {
	
		getTextArea().addCaretListener(listener);
	}
	
	//
	// Overrides this method to watch the listener installed.
	//
	public void addInputMethodListener(InputMethodListener l) {
	
		getTextArea().addInputMethodListener(l);
	}
	
	/**
	 * Appends the given text to the end of the document. Does nothing if
	 * the model is null or the string is null or empty.
	 *
	 * @param str
	 *        the text to insert
	 * @see #insert
	 */
	public void append(String str) {
	
		getTextArea().append(str);
	}
	
	/**
	 * Transfers the currently selected range in the associated
	 * text model to the system clipboard, leaving the contents
	 * in the text model. The current selection remains intact.
	 * Does nothing for <code>null</code> selections.
	 *
	 * @see java.awt.Toolkit#getSystemClipboard
	 * @see java.awt.datatransfer.Clipboard
	 */
	public void copy() {
	
		getTextArea().copy();
	}
	
	/**
	 * Transfers the currently selected range in the associated
	 * text model to the system clipboard, removing the contents
	 * from the model. The current selection is reset. Does nothing
	 * for <code>null</code> selections.
	 *
	 * @see java.awt.Toolkit#getSystemClipboard
	 * @see java.awt.datatransfer.Clipboard
	 */
	public void cut() {
	
		getTextArea().cut();
	}
	
	/**
	 * Gets the <code>AccessibleContext</code> associated with this <code>JTextComponent</code>. For text components,
	 * the <code>AccessibleContext</code> takes the form of an <code>AccessibleJTextComponent</code>.
	 * A new <code>AccessibleJTextComponent</code> instance
	 * is created if necessary.
	 *
	 * @return an <code>AccessibleJTextComponent</code> that serves as the <code>AccessibleContext</code> of this <code>JTextComponent</code>
	 */
	public AccessibleContext getAccessibleContext() {
	
		return getTextArea().getAccessibleContext();
	}
	
	/**
	 * Fetches the command list for the editor. This is
	 * the list of commands supported by the plugged-in UI
	 * augmented by the collection of commands that the
	 * editor itself supports. These are useful for binding
	 * to events, such as in a keymap.
	 *
	 * @return the command list
	 */
	public Action[] getActions() {
	
		return getTextArea().getActions();
	}
	
	/**
	 * Fetches the caret that allows text-oriented navigation over
	 * the view.
	 *
	 * @return the caret
	 */
	@Transient
	public Caret getCaret() {
	
		return getTextArea().getCaret();
	}
	
	/**
	 * Fetches the current color used to render the
	 * caret.
	 *
	 * @return the color
	 */
	public Color getCaretColor() {
	
		return getTextArea().getCaretColor();
	}
	
	/**
	 * Returns an array of all the caret listeners
	 * registered on this text component.
	 *
	 * @return all of this component's <code>CaretListener</code>s
	 *         or an empty
	 *         array if no caret listeners are currently registered
	 * @see #addCaretListener
	 * @see #removeCaretListener
	 * @since 1.4
	 */
	public CaretListener[] getCaretListeners() {
	
		return getTextArea().getCaretListeners();
	}
	
	/**
	 * Returns the position of the text insertion caret for the
	 * text component.
	 *
	 * @return the position of the text insertion caret for the
	 *         text component >= 0
	 */
	@Transient
	public int getCaretPosition() {
	
		return getTextArea().getCaretPosition();
	}
	
	/**
	 * Returns the number of columns in the TextArea.
	 *
	 * @return number of columns >= 0
	 */
	public int getColumns() {
	
		return getTextArea().getColumns();
	}
	
	/**
	 * Fetches the current color used to render the
	 * disabled text.
	 *
	 * @return the color
	 */
	public Color getDisabledTextColor() {
	
		return getTextArea().getDisabledTextColor();
	}
	
	/**
	 * Fetches the model associated with the editor. This is
	 * primarily for the UI to get at the minimal amount of
	 * state required to be a text editor. Subclasses will
	 * return the actual type of the model which will typically
	 * be something that extends Document.
	 *
	 * @return the model
	 */
	public Document getDocument() {
	
		return getTextArea().getDocument();
	}
	
	/**
	 * Returns whether or not automatic drag handling is enabled.
	 *
	 * @return the value of the {@code dragEnabled} property
	 * @see #setDragEnabled
	 * @since 1.4
	 */
	public boolean getDragEnabled() {
	
		return getTextArea().getDragEnabled();
	}
	
	/**
	 * Returns the location that this component should visually indicate
	 * as the drop location during a DnD operation over the component,
	 * or {@code null} if no location is to currently be shown.
	 * <p>
	 * This method is not meant for querying the drop location from a {@code TransferHandler}, as the drop location is only set after the {@code TransferHandler}'s <code>canImport</code> has returned and has allowed for the location to be shown.
	 * <p>
	 * When this property changes, a property change event with name "dropLocation" is fired by the component.
	 *
	 * @return the drop location
	 * @see #setDropMode
	 * @see TransferHandler#canImport(TransferHandler.TransferSupport)
	 * @since 1.6
	 */
	public final DropLocation getDropLocation() {
	
		return getTextArea().getDropLocation();
	}
	
	/**
	 * Returns the drop mode for this component.
	 *
	 * @return the drop mode for this component
	 * @see #setDropMode
	 * @since 1.6
	 */
	public final DropMode getDropMode() {
	
		return getTextArea().getDropMode();
	}
	
	/**
	 * Returns the key accelerator that will cause the receiving
	 * text component to get the focus. Return '\0' if no focus
	 * accelerator has been set.
	 *
	 * @return the key
	 */
	public char getFocusAccelerator() {
	
		return getTextArea().getFocusAccelerator();
	}
	
	/**
	 * Fetches the object responsible for making highlights.
	 *
	 * @return the highlighter
	 */
	public Highlighter getHighlighter() {
	
		return getTextArea().getHighlighter();
	}
	
	@Override
	public int getIndex() {
	
		return getTextArea().getIndex();
	}
	
	//
	// Overrides this method to become an active input method client.
	//
	public InputMethodRequests getInputMethodRequests() {
	
		return getTextArea().getInputMethodRequests();
	}
	
	/**
	 * Fetches the keymap currently active in this text
	 * component.
	 *
	 * @return the keymap
	 */
	public Keymap getKeymap() {
	
		return getTextArea().getKeymap();
	}
	
	/**
	 * Determines the number of lines contained in the area.
	 *
	 * @return the number of lines > 0
	 */
	public int getLineCount() {
	
		return getTextArea().getLineCount();
	}
	
	/**
	 * Determines the offset of the end of the given line.
	 *
	 * @param line
	 *        the line >= 0
	 * @return the offset >= 0
	 * @exception BadLocationException
	 *            Thrown if the line is
	 *            less than zero or greater or equal to the number of
	 *            lines contained in the document (as reported by
	 *            getLineCount).
	 */
	public int getLineEndOffset(int line) throws BadLocationException {
	
		return getTextArea().getLineEndOffset(line);
	}
	
	/**
	 * Translates an offset into the components text to a
	 * line number.
	 *
	 * @param offset
	 *        the offset >= 0
	 * @return the line number >= 0
	 * @exception BadLocationException
	 *            thrown if the offset is
	 *            less than zero or greater than the document length.
	 */
	public int getLineOfOffset(int offset) throws BadLocationException {
	
		return getTextArea().getLineOfOffset(offset);
	}
	
	/**
	 * Determines the offset of the start of the given line.
	 *
	 * @param line
	 *        the line number to translate >= 0
	 * @return the offset >= 0
	 * @exception BadLocationException
	 *            thrown if the line is
	 *            less than zero or greater or equal to the number of
	 *            lines contained in the document (as reported by
	 *            getLineCount).
	 */
	public int getLineStartOffset(int line) throws BadLocationException {
	
		return getTextArea().getLineStartOffset(line);
	}
	
	/**
	 * Gets the line-wrapping policy of the text area. If set
	 * to true the lines will be wrapped if they are too long
	 * to fit within the allocated width. If set to false,
	 * the lines will always be unwrapped.
	 *
	 * @return if lines will be wrapped
	 */
	public boolean getLineWrap() {
	
		return getTextArea().getLineWrap();
	}
	
	/**
	 * Returns the margin between the text component's border and
	 * its text.
	 *
	 * @return the margin
	 */
	public Insets getMargin() {
	
		return getTextArea().getMargin();
	}
	
	/**
	 * Returns the <code>NavigationFilter</code>. <code>NavigationFilter</code> is used by <code>DefaultCaret</code> and the default cursor movement
	 * actions as a way to restrict the cursor movement. A null return value
	 * implies the cursor movement and selection should not be restricted.
	 *
	 * @since 1.4
	 * @return the NavigationFilter
	 */
	public NavigationFilter getNavigationFilter() {
	
		return getTextArea().getNavigationFilter();
	}
	
	/**
	 * Returns the preferred size of the viewport if this component
	 * is embedded in a JScrollPane. This uses the desired column
	 * and row settings if they have been set, otherwise the superclass
	 * behavior is used.
	 *
	 * @return The preferredSize of a JViewport whose view is this Scrollable.
	 * @see JViewport#getPreferredSize
	 */
	public Dimension getPreferredScrollableViewportSize() {
	
		return getTextArea().getPreferredScrollableViewportSize();
	}
	
	/**
	 * Returns a {@code Printable} to use for printing the content of this {@code JTextComponent}. The returned {@code Printable} prints
	 * the document as it looks on the screen except being reformatted
	 * to fit the paper.
	 * The returned {@code Printable} can be wrapped inside another {@code Printable} in order to create complex reports and
	 * documents.
	 * <p>
	 * The returned {@code Printable} shares the {@code document} with this {@code JTextComponent}. It is the responsibility of the developer to ensure that the {@code document} is not mutated while this {@code Printable} is used. Printing behavior is undefined when the {@code document} is mutated during printing.
	 * <p>
	 * Page header and footer text can be added to the output by providing {@code MessageFormat} arguments. The printing code requests {@code Strings} from the formats, providing a single item which may be included in the formatted string: an {@code Integer} representing the current page number.
	 * <p>
	 * The returned {@code Printable} when printed, formats the document content appropriately for the page size. For correct line wrapping the {@code imageable width} of all pages must be the same. See {@link java.awt.print.PageFormat#getImageableWidth}.
	 * <p>
	 * This method is thread-safe, although most Swing methods are not. Please see <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html"> How to Use Threads</A> for more information.
	 * <p>
	 * The returned {@code Printable} can be printed on any thread.
	 * <p>
	 * This implementation returned {@code Printable} performs all painting on the <i>Event Dispatch Thread</i>, regardless of what thread it is used on.
	 *
	 * @param headerFormat
	 *        the text, in {@code MessageFormat}, to be
	 *        used as the header, or {@code null} for no header
	 * @param footerFormat
	 *        the text, in {@code MessageFormat}, to be
	 *        used as the footer, or {@code null} for no footer
	 * @return a {@code Printable} for use in printing content of this {@code JTextComponent}
	 * @see java.awt.print.Printable
	 * @see java.awt.print.PageFormat
	 * @see javax.swing.text.Document#render(java.lang.Runnable)
	 * @since 1.6
	 */
	public Printable getPrintable(final MessageFormat headerFormat, final MessageFormat footerFormat) {
	
		return getTextArea().getPrintable(headerFormat, footerFormat);
	}
	
	/**
	 * Returns the number of rows in the TextArea.
	 *
	 * @return the number of rows >= 0
	 */
	public int getRows() {
	
		return getTextArea().getRows();
	}
	
	/**
	 * Components that display logical rows or columns should compute
	 * the scroll increment that will completely expose one block
	 * of rows or columns, depending on the value of orientation.
	 * <p>
	 * The default implementation of this is to simply return the visible area. Subclasses will likely be able to provide a much more reasonable value.
	 *
	 * @param visibleRect
	 *        the view area visible within the viewport
	 * @param orientation
	 *        either <code>SwingConstants.VERTICAL</code> or <code>SwingConstants.HORIZONTAL</code>
	 * @param direction
	 *        less than zero to scroll up/left, greater than zero
	 *        for down/right
	 * @return the "block" increment for scrolling in the specified direction
	 * @exception IllegalArgumentException
	 *            for an invalid orientation
	 * @see JScrollBar#setBlockIncrement
	 */
	public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
	
		return getTextArea().getScrollableBlockIncrement(visibleRect, orientation, direction);
	}
	
	/**
	 * Returns true if a viewport should always force the height of this <code>Scrollable</code> to match the height of the viewport.
	 * For example a columnar text view that flowed text in left to
	 * right columns could effectively disable vertical scrolling by
	 * returning true here.
	 * <p>
	 * Scrolling containers, like <code>JViewport</code>, will use this method each time they are validated.
	 *
	 * @return true if a viewport should force the Scrollables height
	 *         to match its own
	 */
	public boolean getScrollableTracksViewportHeight() {
	
		return getTextArea().getScrollableTracksViewportHeight();
	}
	
	/**
	 * Returns true if a viewport should always force the width of this
	 * Scrollable to match the width of the viewport. This is implemented
	 * to return true if the line wrapping policy is true, and false
	 * if lines are not being wrapped.
	 *
	 * @return true if a viewport should force the Scrollables width
	 *         to match its own.
	 */
	public boolean getScrollableTracksViewportWidth() {
	
		return getTextArea().getScrollableTracksViewportWidth();
	}
	
	/**
	 * Components that display logical rows or columns should compute
	 * the scroll increment that will completely expose one new row
	 * or column, depending on the value of orientation. This is implemented
	 * to use the values returned by the <code>getRowHeight</code> and <code>getColumnWidth</code> methods.
	 * <p>
	 * Scrolling containers, like JScrollPane, will use this method each time the user requests a unit scroll.
	 *
	 * @param visibleRect
	 *        the view area visible within the viewport
	 * @param orientation
	 *        Either SwingConstants.VERTICAL or
	 *        SwingConstants.HORIZONTAL.
	 * @param direction
	 *        Less than zero to scroll up/left,
	 *        greater than zero for down/right.
	 * @return The "unit" increment for scrolling in the specified direction
	 * @exception IllegalArgumentException
	 *            for an invalid orientation
	 * @see JScrollBar#setUnitIncrement
	 * @see #getRowHeight
	 * @see #getColumnWidth
	 */
	public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
	
		return getTextArea().getScrollableUnitIncrement(visibleRect, orientation, direction);
	}
	
	/**
	 * @return the scrollPane
	 */
	public final JScrollPane getScrollPane() {
	
		if(scrollPane == null) {
			scrollPane = new JScrollPane(getTextArea());
		}
		return scrollPane;
	}
	
	/**
	 * Returns the selected text contained in this <code>TextComponent</code>. If the selection is <code>null</code> or the document empty, returns <code>null</code>.
	 *
	 * @return the text
	 * @exception IllegalArgumentException
	 *            if the selection doesn't
	 *            have a valid mapping into the document for some reason
	 * @see #setText
	 */
	public String getSelectedText() {
	
		return getTextArea().getSelectedText();
	}
	
	/**
	 * Fetches the current color used to render the
	 * selected text.
	 *
	 * @return the color
	 */
	public Color getSelectedTextColor() {
	
		return getTextArea().getSelectedTextColor();
	}
	
	/**
	 * Fetches the current color used to render the
	 * selection.
	 *
	 * @return the color
	 */
	public Color getSelectionColor() {
	
		return getTextArea().getSelectionColor();
	}
	
	/**
	 * Returns the selected text's end position. Return 0 if the document
	 * is empty, or the value of dot if there is no selection.
	 *
	 * @return the end position >= 0
	 */
	@Transient
	public int getSelectionEnd() {
	
		return getTextArea().getSelectionEnd();
	}
	
	/**
	 * Returns the selected text's start position. Return 0 for an
	 * empty document, or the value of dot if no selection.
	 *
	 * @return the start position >= 0
	 */
	@Transient
	public int getSelectionStart() {
	
		return getTextArea().getSelectionStart();
	}
	
	/**
	 * Gets the number of characters used to expand tabs. If the document is
	 * null or doesn't have a tab setting, return a default of 8.
	 *
	 * @return the number of characters
	 */
	public int getTabSize() {
	
		return getTextArea().getTabSize();
	}
	
	/**
	 * Returns the text contained in this <code>TextComponent</code>.
	 * If the underlying document is <code>null</code>,
	 * will give a <code>NullPointerException</code>.
	 * Note that text is not a bound property, so no <code>PropertyChangeEvent
	 * </code> is fired when it changes. To listen for changes to the text,
	 * use <code>DocumentListener</code>.
	 *
	 * @return the text
	 * @exception NullPointerException
	 *            if the document is <code>null</code>
	 * @see #setText
	 */
	public String getText() {
	
		return getTextArea().getText();
	}
	
	/**
	 * Fetches a portion of the text represented by the
	 * component. Returns an empty string if length is 0.
	 *
	 * @param offs
	 *        the offset >= 0
	 * @param len
	 *        the length >= 0
	 * @return the text
	 * @exception BadLocationException
	 *            if the offset or length are invalid
	 */
	public String getText(int offs, int len) throws BadLocationException {
	
		return getTextArea().getText(offs, len);
	}
	
	/**
	 * @return the textArea
	 */
	public final TextArea getTextArea() {
	
		return textArea;
	}
	
	/**
	 * Returns the string to be used as the tooltip for <code>event</code>.
	 * This will return one of:
	 * <ol>
	 * <li>If <code>setToolTipText</code> has been invoked with a non-<code>null</code> value, it will be returned, otherwise
	 * <li>The value from invoking <code>getToolTipText</code> on the UI will be returned.
	 * </ol>
	 * By default <code>JTextComponent</code> does not register
	 * itself with the <code>ToolTipManager</code>.
	 * This means that tooltips will NOT be shown from the <code>TextUI</code> unless <code>registerComponent</code> has
	 * been invoked on the <code>ToolTipManager</code>.
	 *
	 * @param event
	 *        the event in question
	 * @return the string to be used as the tooltip for <code>event</code>
	 * @see javax.swing.JComponent#setToolTipText
	 * @see javax.swing.plaf.TextUI#getToolTipText
	 * @see javax.swing.ToolTipManager#registerComponent
	 */
	public String getToolTipText(MouseEvent event) {
	
		return getTextArea().getToolTipText(event);
	}
	
	/**
	 * Gets the style of wrapping used if the text area is wrapping
	 * lines. If set to true the lines will be wrapped at word
	 * boundaries (ie whitespace) if they are too long
	 * to fit within the allocated width. If set to false,
	 * the lines will be wrapped at character boundaries.
	 *
	 * @return if the wrap style should be word boundaries
	 *         instead of character boundaries
	 * @see #setWrapStyleWord
	 */
	public boolean getWrapStyleWord() {
	
		return getTextArea().getWrapStyleWord();
	}
	
	/**
	 * Inserts the specified text at the specified position. Does nothing
	 * if the model is null or if the text is null or empty.
	 *
	 * @param str
	 *        the text to insert
	 * @param pos
	 *        the position at which to insert >= 0
	 * @exception IllegalArgumentException
	 *            if pos is an
	 *            invalid position in the model
	 * @see TextComponent#setText
	 * @see #replaceRange
	 */
	public void insert(String str, int pos) {
	
		getTextArea().insert(str, pos);
	}
	
	@Override
	public boolean isAtributte() {
	
		return getTextArea().isAtributte();
	}
	
	/**
	 * Returns the boolean indicating whether this <code>TextComponent</code> is editable or not.
	 *
	 * @return the boolean value
	 * @see #setEditable
	 */
	public boolean isEditable() {
	
		return getTextArea().isEditable();
	}
	
	@Override
	public boolean isRequired() {
	
		return getTextArea().isRequired();
	}
	
	@Override
	public boolean isRequiredBorderEnabled() {
	
		return requiredBorderEnabled;
	}
	
	/**
	 * Converts the given location in the model to a place in
	 * the view coordinate system.
	 * The component must have a positive size for
	 * this translation to be computed (i.e. layout cannot
	 * be computed until the component has been sized). The
	 * component does not have to be visible or painted.
	 *
	 * @param pos
	 *        the position >= 0
	 * @return the coordinates as a rectangle, with (r.x, r.y) as the location
	 *         in the coordinate system, or null if the component does
	 *         not yet have a positive size.
	 * @exception BadLocationException
	 *            if the given position does not
	 *            represent a valid location in the associated document
	 * @see TextUI#modelToView
	 */
	public Rectangle modelToView(int pos) throws BadLocationException {
	
		return getTextArea().modelToView(pos);
	}
	
	/**
	 * Moves the caret to a new position, leaving behind a mark
	 * defined by the last time <code>setCaretPosition</code> was
	 * called. This forms a selection.
	 * If the document is <code>null</code>, does nothing. The position
	 * must be between 0 and the length of the component's text or else
	 * an exception is thrown.
	 *
	 * @param pos
	 *        the position
	 * @exception IllegalArgumentException
	 *            if the value supplied
	 *            for <code>position</code> is less than zero or greater
	 *            than the component's text length
	 * @see #setCaretPosition
	 */
	public void moveCaretPosition(int pos) {
	
		getTextArea().moveCaretPosition(pos);
	}
	
	/**
	 * Transfers the contents of the system clipboard into the
	 * associated text model. If there is a selection in the
	 * associated view, it is replaced with the contents of the
	 * clipboard. If there is no selection, the clipboard contents
	 * are inserted in front of the current insert position in
	 * the associated view. If the clipboard is empty, does nothing.
	 *
	 * @see #replaceSelection
	 * @see java.awt.Toolkit#getSystemClipboard
	 * @see java.awt.datatransfer.Clipboard
	 */
	public void paste() {
	
		getTextArea().paste();
	}
	
	/**
	 * A convenience print method that displays a print dialog, and then
	 * prints this {@code JTextComponent} in <i>interactive</i> mode with no
	 * header or footer text. Note: this method
	 * blocks until printing is done.
	 * <p>
	 * Note: In <i>headless</i> mode, no dialogs will be shown.
	 * <p>
	 * This method calls the full featured {@link #print(MessageFormat, MessageFormat, boolean, PrintService, PrintRequestAttributeSet, boolean)
	 * print} method to perform printing.
	 * 
	 * @return {@code true}, unless printing is canceled by the user
	 * @throws PrinterException
	 *         if an error in the print system causes the job
	 *         to be aborted
	 * @throws SecurityException
	 *         if this thread is not allowed to
	 *         initiate a print job request
	 * @see #print(MessageFormat, MessageFormat, boolean, PrintService, PrintRequestAttributeSet, boolean)
	 * @since 1.6
	 */
	
	public boolean print() throws PrinterException {
	
		return getTextArea().print();
	}
	
	/**
	 * A convenience print method that displays a print dialog, and then
	 * prints this {@code JTextComponent} in <i>interactive</i> mode with
	 * the specified header and footer text. Note: this method
	 * blocks until printing is done.
	 * <p>
	 * Note: In <i>headless</i> mode, no dialogs will be shown.
	 * <p>
	 * This method calls the full featured {@link #print(MessageFormat, MessageFormat, boolean, PrintService, PrintRequestAttributeSet, boolean)
	 * print} method to perform printing.
	 * 
	 * @param headerFormat
	 *        the text, in {@code MessageFormat}, to be
	 *        used as the header, or {@code null} for no header
	 * @param footerFormat
	 *        the text, in {@code MessageFormat}, to be
	 *        used as the footer, or {@code null} for no footer
	 * @return {@code true}, unless printing is canceled by the user
	 * @throws PrinterException
	 *         if an error in the print system causes the job
	 *         to be aborted
	 * @throws SecurityException
	 *         if this thread is not allowed to
	 *         initiate a print job request
	 * @see #print(MessageFormat, MessageFormat, boolean, PrintService, PrintRequestAttributeSet, boolean)
	 * @see java.text.MessageFormat
	 * @since 1.6
	 */
	public boolean print(final MessageFormat headerFormat, final MessageFormat footerFormat) throws PrinterException {
	
		return getTextArea().print(headerFormat, footerFormat);
	}
	
	/**
	 * Prints the content of this {@code JTextComponent}. Note: this method
	 * blocks until printing is done.
	 * <p>
	 * Page header and footer text can be added to the output by providing {@code MessageFormat} arguments. The printing code requests {@code Strings} from the formats, providing a single item which may be included in the formatted string: an {@code Integer} representing the current page number.
	 * <p>
	 * {@code showPrintDialog boolean} parameter allows you to specify whether a print dialog is displayed to the user. When it is, the user may use the dialog to change printing attributes or even cancel the print.
	 * <p>
	 * {@code service} allows you to provide the initial {@code PrintService} for the print dialog, or to specify {@code PrintService} to print to when the dialog is not shown.
	 * <p>
	 * {@code attributes} can be used to provide the initial values for the print dialog, or to supply any needed attributes when the dialog is not shown. {@code attributes} can be used to control how the job will print, for example <i>duplex</i> or <i>single-sided</i>.
	 * <p>
	 * {@code interactive boolean} parameter allows you to specify whether to perform printing in <i>interactive</i> mode. If {@code true}, a progress dialog, with an abort option, is displayed for the duration of printing. This dialog is <i>modal</i> when {@code print} is invoked on the <i>Event Dispatch Thread</i> and <i>non-modal</i> otherwise. <b>Warning</b>: calling this method on the <i>Event Dispatch Thread</i> with {@code interactive false} blocks <i>all</i> events, including repaints, from being processed until printing is complete. It is only recommended when printing from an application with no visible GUI.
	 * <p>
	 * Note: In <i>headless</i> mode, {@code showPrintDialog} and {@code interactive} parameters are ignored and no dialogs are shown.
	 * <p>
	 * This method ensures the {@code document} is not mutated during printing. To indicate it visually, {@code setEnabled(false)} is set for the duration of printing.
	 * <p>
	 * This method uses {@link #getPrintable} to render document content.
	 * <p>
	 * This method is thread-safe, although most Swing methods are not. Please see <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html"> How to Use Threads</A> for more information.
	 * <p>
	 * <b>Sample Usage</b>. This code snippet shows a cross-platform print dialog and then prints the {@code JTextComponent} in <i>interactive</i> mode unless the user cancels the dialog:
	 *
	 * <pre>
	 * textComponent.print(new MessageFormat(&quot;My text component header&quot;), new MessageFormat(&quot;Footer. Page - {0}&quot;), true, null, null, true);
	 * </pre>
	 * <p>
	 * Executing this code off the <i>Event Dispatch Thread</i> performs printing on the <i>background</i>. The following pattern might be used for <i>background</i> printing:
	 * 
	 * <pre>
	 *     FutureTask&lt;Boolean&gt; future =
	 *         new FutureTask&lt;Boolean&gt;(
	 *             new Callable&lt;Boolean&gt;() {
	 *                 public Boolean call() {
	 *                     return textComponent.print(.....);
	 *                 }
	 *             });
	 *     executor.execute(future);
	 * </pre>
	 *
	 * @param headerFormat
	 *        the text, in {@code MessageFormat}, to be
	 *        used as the header, or {@code null} for no header
	 * @param footerFormat
	 *        the text, in {@code MessageFormat}, to be
	 *        used as the footer, or {@code null} for no footer
	 * @param showPrintDialog
	 *        {@code true} to display a print dialog, {@code false} otherwise
	 * @param service
	 *        initial {@code PrintService}, or {@code null} for the
	 *        default
	 * @param attributes
	 *        the job attributes to be applied to the print job, or {@code null} for none
	 * @param interactive
	 *        whether to print in an interactive mode
	 * @return {@code true}, unless printing is canceled by the user
	 * @throws PrinterException
	 *         if an error in the print system causes the job
	 *         to be aborted
	 * @throws SecurityException
	 *         if this thread is not allowed to
	 *         initiate a print job request
	 * @see #getPrintable
	 * @see java.text.MessageFormat
	 * @see java.awt.GraphicsEnvironment#isHeadless
	 * @see java.util.concurrent.FutureTask
	 * @since 1.6
	 */
	public boolean print(final MessageFormat headerFormat, final MessageFormat footerFormat, final boolean showPrintDialog, final PrintService service, final PrintRequestAttributeSet attributes, final boolean interactive) throws PrinterException {
	
		return getTextArea().print(headerFormat, footerFormat, showPrintDialog, service, attributes, interactive);
	}
	
	/**
	 * Initializes from a stream. This creates a
	 * model of the type appropriate for the component
	 * and initializes the model from the stream.
	 * By default this will load the model as plain
	 * text. Previous contents of the model are discarded.
	 *
	 * @param in
	 *        the stream to read from
	 * @param desc
	 *        an object describing the stream; this
	 *        might be a string, a File, a URL, etc. Some kinds
	 *        of documents (such as html for example) might be
	 *        able to make use of this information; if non-<code>null</code>,
	 *        it is added as a property of the document
	 * @exception IOException
	 *            as thrown by the stream being
	 *            used to initialize
	 * @see EditorKit#createDefaultDocument
	 * @see #setDocument
	 * @see PlainDocument
	 */
	public void read(Reader in, Object desc) throws IOException {
	
		getTextArea().read(in, desc);
	}
	
	/**
	 * Removes a caret listener.
	 *
	 * @param listener
	 *        the listener to be removed
	 * @see javax.swing.event.CaretEvent
	 */
	public void removeCaretListener(CaretListener listener) {
	
		getTextArea().removeCaretListener(listener);
	}
	
	public void removeNotify() {
	
		getTextArea().removeNotify();
	}
	
	/**
	 * @param oldValue
	 * @param newValue
	 * @param caseSensitive
	 */
	public final void replaceAll(String oldValue, String newValue, boolean caseSensitive) {
	
		getTextArea().replaceAll(oldValue, newValue, caseSensitive);
	}
	
	/**
	 * Replaces text from the indicated start to end position with the
	 * new text specified. Does nothing if the model is null. Simply
	 * does a delete if the new string is null or empty.
	 *
	 * @param str
	 *        the text to use as the replacement
	 * @param start
	 *        the start position >= 0
	 * @param end
	 *        the end position >= start
	 * @exception IllegalArgumentException
	 *            if part of the range is an
	 *            invalid position in the model
	 * @see #insert
	 * @see #replaceRange
	 */
	public void replaceRange(String str, int start, int end) {
	
		getTextArea().replaceRange(str, start, end);
	}
	
	/**
	 * @param newValue
	 */
	public final void replaceSelection(String newValue) {
	
		getTextArea().replaceSelection(newValue);
	}
	
	/**
	 * @param value
	 * @param initPosition
	 * @param caseSensitive
	 * @return endPosition or <b>-1</b> if no such value
	 */
	public final int searchAndSelect(String value, int initPosition, boolean caseSensitive) {
	
		return getTextArea().searchAndSelect(value, initPosition, caseSensitive);
	}
	
	/**
	 * Selects the text between the specified start and end positions.
	 * <p>
	 * This method sets the start and end positions of the selected text, enforcing the restriction that the start position must be greater than or equal to zero. The end position must be greater than or equal to the start position, and less than or equal to the length of the text component's text.
	 * <p>
	 * If the caller supplies values that are inconsistent or out of bounds, the method enforces these constraints silently, and without failure. Specifically, if the start position or end position is greater than the length of the text, it is reset to equal the text length. If the start position is less than zero, it is reset to zero, and if the end position is less than the start position, it is reset to the start position.
	 * <p>
	 * This call is provided for backward compatibility. It is routed to a call to <code>setCaretPosition</code> followed by a call to <code>moveCaretPosition</code>. The preferred way to manage selection is by calling those methods directly.
	 *
	 * @param selectionStart
	 *        the start position of the text
	 * @param selectionEnd
	 *        the end position of the text
	 * @see #setCaretPosition
	 * @see #moveCaretPosition
	 */
	public void select(int selectionStart, int selectionEnd) {
	
		getTextArea().select(selectionStart, selectionEnd);
	}
	
	/**
	 * Selects all the text in the <code>TextComponent</code>.
	 * Does nothing on a <code>null</code> or empty document.
	 */
	public void selectAll() {
	
		getTextArea().selectAll();
	}
	
	@Override
	public void setAtributte(final boolean atributte) {
	
		getTextArea().setAtributte(atributte);
	}
	
	/**
	 * Sets the caret to be used. By default this will be set
	 * by the UI that gets installed. This can be changed to
	 * a custom caret if desired. Setting the caret results in a
	 * PropertyChange event ("caret") being fired.
	 *
	 * @param c
	 *        the caret
	 * @see #getCaret
	 * @beaninfo
	 *           description: the caret used to select/navigate
	 *           bound: true
	 *           expert: true
	 */
	public void setCaret(Caret c) {
	
		getTextArea().setCaret(c);
	}
	
	/**
	 * Sets the current color used to render the caret.
	 * Setting to <code>null</code> effectively restores the default color.
	 * Setting the color results in a PropertyChange event ("caretColor")
	 * being fired.
	 *
	 * @param c
	 *        the color
	 * @see #getCaretColor
	 * @beaninfo
	 *           description: the color used to render the caret
	 *           bound: true
	 *           preferred: true
	 */
	public void setCaretColor(Color c) {
	
		getTextArea().setCaretColor(c);
	}
	
	/**
	 * Sets the position of the text insertion caret for the <code>TextComponent</code>. Note that the caret tracks change,
	 * so this may move if the underlying text of the component is changed.
	 * If the document is <code>null</code>, does nothing. The position
	 * must be between 0 and the length of the component's text or else
	 * an exception is thrown.
	 *
	 * @param position
	 *        the position
	 * @exception IllegalArgumentException
	 *            if the value supplied
	 *            for <code>position</code> is less than zero or greater
	 *            than the component's text length
	 * @beaninfo
	 *           description: the caret position
	 */
	public void setCaretPosition(int position) {
	
		getTextArea().setCaretPosition(position);
	}
	
	/**
	 * Sets the number of columns for this TextArea. Does an invalidate()
	 * after setting the new value.
	 *
	 * @param columns
	 *        the number of columns >= 0
	 * @exception IllegalArgumentException
	 *            if columns is less than 0
	 * @see #getColumns
	 * @beaninfo
	 *           description: the number of columns preferred for display
	 */
	public void setColumns(int columns) {
	
		getTextArea().setColumns(columns);
	}
	
	// Override of Component.setComponentOrientation
	public void setComponentOrientation(ComponentOrientation o) {
	
		getTextArea().setComponentOrientation(o);
	}
	
	/**
	 * Sets the current color used to render the
	 * disabled text. Setting the color fires off a
	 * PropertyChange event ("disabledTextColor").
	 *
	 * @param c
	 *        the color
	 * @see #getDisabledTextColor
	 * @beaninfo
	 *           description: color used to render disabled text
	 *           bound: true
	 *           preferred: true
	 */
	public void setDisabledTextColor(Color c) {
	
		getTextArea().setDisabledTextColor(c);
	}
	
	/**
	 * Associates the editor with a text document.
	 * The currently registered factory is used to build a view for
	 * the document, which gets displayed by the editor after revalidation.
	 * A PropertyChange event ("document") is propagated to each listener.
	 *
	 * @param doc
	 *        the document to display/edit
	 * @see #getDocument
	 * @beaninfo
	 *           description: the text document model
	 *           bound: true
	 *           expert: true
	 */
	public void setDocument(Document doc) {
	
		getTextArea().setDocument(doc);
	}
	
	/**
	 * Turns on or off automatic drag handling. In order to enable automatic
	 * drag handling, this property should be set to {@code true}, and the
	 * component's {@code TransferHandler} needs to be {@code non-null}.
	 * The default value of the {@code dragEnabled} property is {@code false}.
	 * <p>
	 * The job of honoring this property, and recognizing a user drag gesture, lies with the look and feel implementation, and in particular, the component's {@code TextUI}. When automatic drag handling is enabled, most look and feels (including those that subclass {@code BasicLookAndFeel}) begin a drag and drop operation whenever the user presses the mouse button over a selection and then moves the mouse a few pixels. Setting this property to {@code true} can therefore have a subtle effect on how selections behave.
	 * <p>
	 * If a look and feel is used that ignores this property, you can still begin a drag and drop operation by calling {@code exportAsDrag} on the component's {@code TransferHandler}.
	 *
	 * @param b
	 *        whether or not to enable automatic drag handling
	 * @exception HeadlessException
	 *            if <code>b</code> is <code>true</code> and <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
	 * @see java.awt.GraphicsEnvironment#isHeadless
	 * @see #getDragEnabled
	 * @see #setTransferHandler
	 * @see TransferHandler
	 * @since 1.4
	 * @beaninfo
	 *           description: determines whether automatic drag handling is enabled
	 *           bound: false
	 */
	public void setDragEnabled(boolean b) {
	
		getTextArea().setDragEnabled(b);
	}
	
	/**
	 * Sets the drop mode for this component. For backward compatibility,
	 * the default for this property is <code>DropMode.USE_SELECTION</code>.
	 * Usage of <code>DropMode.INSERT</code> is recommended, however,
	 * for an improved user experience. It offers similar behavior of dropping
	 * between text locations, but does so without affecting the actual text
	 * selection and caret location.
	 * <p>
	 * <code>JTextComponents</code> support the following drop modes:
	 * <ul>
	 * <li><code>DropMode.USE_SELECTION</code></li>
	 * <li><code>DropMode.INSERT</code></li>
	 * </ul>
	 * <p>
	 * The drop mode is only meaningful if this component has a <code>TransferHandler</code> that accepts drops.
	 *
	 * @param dropMode
	 *        the drop mode to use
	 * @throws IllegalArgumentException
	 *         if the drop mode is unsupported
	 *         or <code>null</code>
	 * @see #getDropMode
	 * @see #getDropLocation
	 * @see #setTransferHandler
	 * @see javax.swing.TransferHandler
	 * @since 1.6
	 */
	public final void setDropMode(DropMode dropMode) {
	
		getTextArea().setDropMode(dropMode);
	}
	
	/**
	 * Sets the specified boolean to indicate whether or not this <code>TextComponent</code> should be editable.
	 * A PropertyChange event ("editable") is fired when the
	 * state is changed.
	 *
	 * @param b
	 *        the boolean to be set
	 * @see #isEditable
	 * @beaninfo
	 *           description: specifies if the text can be edited
	 *           bound: true
	 */
	public void setEditable(boolean b) {
	
		getTextArea().setEditable(b);
	}
	
	/**
	 * Sets the key accelerator that will cause the receiving text
	 * component to get the focus. The accelerator will be the
	 * key combination of the <em>alt</em> key and the character
	 * given (converted to upper case). By default, there is no focus
	 * accelerator key. Any previous key accelerator setting will be
	 * superseded. A '\0' key setting will be registered, and has the
	 * effect of turning off the focus accelerator. When the new key
	 * is set, a PropertyChange event (FOCUS_ACCELERATOR_KEY) will be fired.
	 *
	 * @param aKey
	 *        the key
	 * @see #getFocusAccelerator
	 * @beaninfo
	 *           description: accelerator character used to grab focus
	 *           bound: true
	 */
	public void setFocusAccelerator(char aKey) {
	
		getTextArea().setFocusAccelerator(aKey);
	}
	
	/**
	 * Sets the current font. This removes cached row height and column
	 * width so the new font will be reflected, and calls revalidate().
	 *
	 * @param f
	 *        the font to use as the current font
	 */
	public void setFont(Font f) {
	
		getTextArea().setFont(f);
	}
	
	/**
	 * Sets the highlighter to be used. By default this will be set
	 * by the UI that gets installed. This can be changed to
	 * a custom highlighter if desired. The highlighter can be set to <code>null</code> to disable it.
	 * A PropertyChange event ("highlighter") is fired
	 * when a new highlighter is installed.
	 *
	 * @param h
	 *        the highlighter
	 * @see #getHighlighter
	 * @beaninfo
	 *           description: object responsible for background highlights
	 *           bound: true
	 *           expert: true
	 */
	public void setHighlighter(Highlighter h) {
	
		getTextArea().setHighlighter(h);
	}
	
	@Override
	public void setIndex(final int index) {
	
		getTextArea().setIndex(index);
	}
	
	/**
	 * Sets the keymap to use for binding events to
	 * actions. Setting to <code>null</code> effectively disables
	 * keyboard input.
	 * A PropertyChange event ("keymap") is fired when a new keymap
	 * is installed.
	 *
	 * @param map
	 *        the keymap
	 * @see #getKeymap
	 * @beaninfo
	 *           description: set of key event to action bindings to use
	 *           bound: true
	 */
	public void setKeymap(Keymap map) {
	
		getTextArea().setKeymap(map);
	}
	
	/**
	 * Sets the line-wrapping policy of the text area. If set
	 * to true the lines will be wrapped if they are too long
	 * to fit within the allocated width. If set to false,
	 * the lines will always be unwrapped. A <code>PropertyChange</code> event ("lineWrap") is fired when the policy is changed.
	 * By default this property is false.
	 *
	 * @param wrap
	 *        indicates if lines should be wrapped
	 * @see #getLineWrap
	 * @beaninfo
	 *           preferred: true
	 *           bound: true
	 *           description: should lines be wrapped
	 */
	public void setLineWrap(boolean wrap) {
	
		getTextArea().setLineWrap(wrap);
	}
	
	/**
	 * Sets margin space between the text component's border
	 * and its text. The text component's default <code>Border</code> object will use this value to create the proper margin.
	 * However, if a non-default border is set on the text component,
	 * it is that <code>Border</code> object's responsibility to create the
	 * appropriate margin space (else this property will effectively
	 * be ignored). This causes a redraw of the component.
	 * A PropertyChange event ("margin") is sent to all listeners.
	 *
	 * @param m
	 *        the space between the border and the text
	 * @beaninfo
	 *           description: desired space between the border and text area
	 *           bound: true
	 */
	public void setMargin(Insets m) {
	
		getTextArea().setMargin(m);
	}
	
	@Override
	public void setName(final String name) {
	
		super.setName(name);
		
		getTextArea().setName(name);
		
		setRequired(isRequired());
	}
	
	/**
	 * Sets the <code>NavigationFilter</code>. <code>NavigationFilter</code> is used by <code>DefaultCaret</code> and the default cursor movement
	 * actions as a way to restrict the cursor movement.
	 *
	 * @since 1.4
	 */
	public void setNavigationFilter(NavigationFilter filter) {
	
		getTextArea().setNavigationFilter(filter);
	}
	
	@Override
	public void setRequired(final boolean required) {
	
		getTextArea().setRequired(required);
		
		//
		if(required) {
			
			//
			if(isRequiredBorderEnabled()) {
				
				setBorder(new LineBorder(Color.RED));
			}
			
			//
			if(CheckUtil.isNullOrAbsoluteEmpty(getName())) {
				
				setToolTipText(I18N.component().requiredThis());
				
			}else {
				
				setToolTipText(I18N.component().requiredField(getName()));
			}
			
		}else {
			
			setBorder(UIManager.getBorder("Panel.border"));
			setToolTipText(null);
		}
	}
	
	@Override
	public void setRequiredBorderEnabled(final boolean requiredBorderEnabled) {
	
		this.requiredBorderEnabled = requiredBorderEnabled;
	}
	
	// --- Tooltip Methods ---------------------------------------------
	
	/**
	 * Sets the number of rows for this TextArea. Calls invalidate() after
	 * setting the new value.
	 *
	 * @param rows
	 *        the number of rows >= 0
	 * @exception IllegalArgumentException
	 *            if rows is less than 0
	 * @see #getRows
	 * @beaninfo
	 *           description: the number of rows preferred for display
	 */
	public void setRows(int rows) {
	
		getTextArea().setRows(rows);
	}
	
	/**
	 * Sets the current color used to render the selected text.
	 * Setting the color to <code>null</code> is the same as <code>Color.black</code>. Setting the color results in a
	 * PropertyChange event ("selectedTextColor") being fired.
	 *
	 * @param c
	 *        the color
	 * @see #getSelectedTextColor
	 * @beaninfo
	 *           description: color used to render selected text
	 *           bound: true
	 *           preferred: true
	 */
	public void setSelectedTextColor(Color c) {
	
		getTextArea().setSelectedTextColor(c);
	}
	
	/**
	 * Sets the current color used to render the selection.
	 * Setting the color to <code>null</code> is the same as setting <code>Color.white</code>. Setting the color results in a
	 * PropertyChange event ("selectionColor").
	 *
	 * @param c
	 *        the color
	 * @see #getSelectionColor
	 * @beaninfo
	 *           description: color used to render selection background
	 *           bound: true
	 *           preferred: true
	 */
	public void setSelectionColor(Color c) {
	
		getTextArea().setSelectionColor(c);
	}
	
	/**
	 * Sets the selection end to the specified position. The new
	 * end point is constrained to be at or after the current
	 * selection start.
	 * <p>
	 * This is available for backward compatibility to code that called this method on <code>java.awt.TextComponent</code>. This is implemented to forward to the <code>Caret</code> implementation which is where the actual selection is maintained.
	 *
	 * @param selectionEnd
	 *        the end position of the text >= 0
	 * @beaninfo
	 *           description: ending location of the selection.
	 */
	public void setSelectionEnd(int selectionEnd) {
	
		getTextArea().setSelectionEnd(selectionEnd);
	}
	
	/**
	 * Sets the selection start to the specified position. The new
	 * starting point is constrained to be before or at the current
	 * selection end.
	 * <p>
	 * This is available for backward compatibility to code that called this method on <code>java.awt.TextComponent</code>. This is implemented to forward to the <code>Caret</code> implementation which is where the actual selection is maintained.
	 *
	 * @param selectionStart
	 *        the start position of the text >= 0
	 * @beaninfo
	 *           description: starting location of the selection.
	 */
	public void setSelectionStart(int selectionStart) {
	
		getTextArea().setSelectionStart(selectionStart);
	}
	
	/**
	 * Sets the number of characters to expand tabs to.
	 * This will be multiplied by the maximum advance for
	 * variable width fonts. A PropertyChange event ("tabSize") is fired
	 * when the tab size changes.
	 *
	 * @param size
	 *        number of characters to expand to
	 * @see #getTabSize
	 * @beaninfo
	 *           preferred: true
	 *           bound: true
	 *           description: the number of characters to expand tabs to
	 */
	public void setTabSize(int size) {
	
		getTextArea().setTabSize(size);
	}
	
	/**
	 * Sets the text of this <code>TextComponent</code> to the specified text. If the text is <code>null</code> or empty, has the effect of simply deleting the old text.
	 * When text has been inserted, the resulting caret location
	 * is determined by the implementation of the caret class.
	 * <p>
	 * Note that text is not a bound property, so no <code>PropertyChangeEvent
	 * </code> is fired when it changes. To listen for changes to the text, use <code>DocumentListener</code>.
	 *
	 * @param t
	 *        the new text to be set
	 * @see #getText
	 * @see DefaultCaret
	 * @beaninfo
	 *           description: the text of this component
	 */
	public void setText(String t) {
	
		getTextArea().setText(t);
	}
	
	/**
	 * Sets the style of wrapping used if the text area is wrapping
	 * lines. If set to true the lines will be wrapped at word
	 * boundaries (whitespace) if they are too long
	 * to fit within the allocated width. If set to false,
	 * the lines will be wrapped at character boundaries.
	 * By default this property is false.
	 *
	 * @param word
	 *        indicates if word boundaries should be used
	 *        for line wrapping
	 * @see #getWrapStyleWord
	 * @beaninfo
	 *           preferred: false
	 *           bound: true
	 *           description: should wrapping occur at word boundaries
	 */
	public void setWrapStyleWord(boolean word) {
	
		getTextArea().setWrapStyleWord(word);
	}
	
	/**
	 * Converts the given place in the view coordinate system
	 * to the nearest representative location in the model.
	 * The component must have a positive size for
	 * this translation to be computed (i.e. layout cannot
	 * be computed until the component has been sized). The
	 * component does not have to be visible or painted.
	 *
	 * @param pt
	 *        the location in the view to translate
	 * @return the offset >= 0 from the start of the document,
	 *         or -1 if the component does not yet have a positive
	 *         size.
	 * @see TextUI#viewToModel
	 */
	public int viewToModel(Point pt) {
	
		return getTextArea().viewToModel(pt);
	}
	
	/**
	 * Stores the contents of the model into the given
	 * stream. By default this will store the model as plain
	 * text.
	 *
	 * @param out
	 *        the output stream
	 * @exception IOException
	 *            on any I/O error
	 */
	public void write(Writer out) throws IOException {
	
		getTextArea().write(out);
	}
	
}
